use std::{fs::File, io::Write as _, path::Path};

use crate::input::Opts;
use e_utils::{fs::AutoPath as _, system::cmd::CmdResult};

/// 系统ROOT
pub const SYSTEM_WIN32: &'static str = "C:\\windows\\system32";
///
pub type CmdRes = CmdResult<Opts>;
use e_utils::AnyResult;

/// 写入bytes
pub fn write_bytes_file(path: impl AsRef<Path>, fname: &str, data: &[u8]) -> AnyResult<()> {
  let path = path.as_ref();
  path.auto_create_dir()?;
  let target = path.join(fname);
  if !target.exists() {
    // 将写入临时文件
    let mut temp_file = File::create(target)?;
    temp_file.write_all(data)?;
  } else if target.is_dir() {
    path.auto_remove_dir()?;
  }
  Ok(())
}

/// 初始化
pub fn default_cmd_res() -> CmdRes {
  CmdRes {
    content: String::new(),
    status: false,
    opts: Opts::default(),
  }
}

/// 初始化
pub fn cmd_res(opts: Opts) -> CmdRes {
  CmdRes {
    content: String::new(),
    status: false,
    opts,
  }
}
/// 获取powershell路径
#[cfg(target_os = "windows")]
#[cfg(feature = "shell")]
pub fn get_powershell_path() -> String {
  unsafe {
    let key_path: Vec<u16> = "SOFTWARE\\Microsoft\\PowerShell\\3\\PowerShellEngine"
      .encode_utf16()
      .chain(Some(0))
      .collect();
    let value_name: Vec<u16> = "ApplicationBase".encode_utf16().chain(Some(0)).collect();
    let mut key: winapi::shared::minwindef::HKEY = std::ptr::null_mut();

    let result: winapi::um::winreg::LSTATUS = winapi::um::winreg::RegOpenKeyExW(
      winapi::um::winreg::HKEY_LOCAL_MACHINE,
      key_path.as_ptr(),
      0,
      winapi::um::winnt::KEY_READ,
      &mut key,
    );

    if result == winapi::shared::winerror::ERROR_SUCCESS as i32 {
      let mut value_len: winapi::shared::minwindef::DWORD = 0;
      let query_result = winapi::um::winreg::RegQueryValueExW(
        key,
        value_name.as_ptr(),
        std::ptr::null_mut(),
        std::ptr::null_mut(),
        std::ptr::null_mut(),
        &mut value_len,
      );

      if query_result == winapi::shared::winerror::ERROR_SUCCESS as i32 {
        let mut buffer: Vec<u16> = vec![0; (value_len / 2) as usize];
        let query_result = winapi::um::winreg::RegQueryValueExW(
          key,
          value_name.as_ptr(),
          std::ptr::null_mut(),
          std::ptr::null_mut(),
          buffer.as_mut_ptr() as *mut u8,
          &mut value_len,
        );

        if query_result == winapi::shared::winerror::ERROR_SUCCESS as i32 {
          winapi::um::winreg::RegCloseKey(key);
          return String::from_utf16_lossy(&buffer)
            .trim_end_matches('\0')
            .to_string();
        }
      }

      winapi::um::winreg::RegCloseKey(key);
    }
  }

  // Fallback to the default PowerShell path if registry lookup fails
  let system32_path =
    std::env::var("SYSTEMROOT").unwrap_or_else(|_| "C:\\Windows\\System32".to_string());
  let power_path = Path::new(&system32_path)
    .join("WindowsPowerShell")
    .join("v1.0");

  if power_path.exists() {
    return power_path.to_string_lossy().into_owned();
  }

  String::new()
}
